home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 1997 September & October / Amiga-CD 1997 #9-10.iso / aminet / gameboyemulator / dasm.c < prev    next >
C/C++ Source or Header  |  1995-10-29  |  10KB  |  218 lines

  1. /** GameBoy Disassembler **************************************/
  2. /**                                                          **/
  3. /**                           dasm.c                         **/
  4. /**                                                          **/
  5. /** This file contains the source of a portable disassembler **/
  6. /** for the customized Z80 CPU used in GameBoy handheld      **/
  7. /** videogame console.                                       **/
  8. /**                                                          **/
  9. /** Copyright (C) Marat Fayzullin 1995                       **/
  10. /**     You are not allowed to distribute this software      **/
  11. /**     commercially. Please, notify me, if you make any     **/
  12. /**     changes to this file.                                **/
  13. /**************************************************************/
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17.  
  18. typedef unsigned char byte;
  19. typedef unsigned short word;
  20.  
  21. void HexByte(char *S,byte V);
  22. void HexWord(char *S,word V);
  23. int DAsm(char *S,byte *A);
  24.  
  25.  
  26. char *Mnemonics[256] =
  27. {
  28.   "NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA",
  29.   "LD (#h),SP","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA",
  30.   "STOP","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA",
  31.   "JR @h","ADD HL,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA",
  32.   "JR NZ,@h","LD HL,#h","LD (HL+),A","INC HL","INC H","DEC H","LD H,*h","DAA",
  33.   "JR Z,@h","ADD HL,HL","LD A,(HL+)","DEC HL","INC L","DEC L","LD L,*h","CPL",
  34.   "JR NC,@h","LD SP,#h","LD (HL-),A","INC SP","INC (HL)","DEC (HL)","LD (HL),*h","SCF",
  35.   "JR C,@h","ADD HL,SP","LD A,(HL-)","DEC SP","INC A","DEC A","LD A,*h","CCF",
  36.   "LD B,B","LD B,C","LD B,D","LD B,E","LD B,H","LD B,L","LD B,(HL)","LD B,A",
  37.   "LD C,B","LD C,C","LD C,D","LD C,E","LD C,H","LD C,L","LD C,(HL)","LD C,A",
  38.   "LD D,B","LD D,C","LD D,D","LD D,E","LD D,H","LD D,L","LD D,(HL)","LD D,A",
  39.   "LD E,B","LD E,C","LD E,D","LD E,E","LD E,H","LD E,L","LD E,(HL)","LD E,A",
  40.   "LD H,B","LD H,C","LD H,D","LD H,E","LD H,H","LD H,L","LD H,(HL)","LD H,A",
  41.   "LD L,B","LD L,C","LD L,D","LD L,E","LD L,H","LD L,L","LD L,(HL)","LD L,A",
  42.   "LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E","LD (HL),H","LD (HL),L","HALT","LD (HL),A",
  43.   "LD A,B","LD A,C","LD A,D","LD A,E","LD A,H","LD A,L","LD A,(HL)","LD A,A",
  44.   "ADD B","ADD C","ADD D","ADD E","ADD H","ADD L","ADD (HL)","ADD A",
  45.   "ADC B","ADC C","ADC D","ADC E","ADC H","ADC L","ADC (HL)","ADC A",
  46.   "SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A",
  47.   "SBC B","SBC C","SBC D","SBC E","SBC H","SBC L","SBC (HL)","SBC A",
  48.   "AND B","AND C","AND D","AND E","AND H","AND L","AND (HL)","AND A",
  49.   "XOR B","XOR C","XOR D","XOR E","XOR H","XOR L","XOR (HL)","XOR A",
  50.   "OR B","OR C","OR D","OR E","OR H","OR L","OR (HL)","OR A",
  51.   "CP B","CP C","CP D","CP E","CP H","CP L","CP (HL)","CP A",
  52.   "RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h",
  53.   "RET Z","RET","JP Z,#h","PREFIX CBh","CALL Z,#h","CALL #h","ADC *h","RST 08h",
  54.   "RET NC","POP DE","JP NC,#h","DB D3h","CALL NC,#h","PUSH DE","SUB *h","RST 10h",
  55.   "RET C","RETI","JP C,#h","DB DBh","CALL C,#h","DB DDh","SBC *h","RST 18h",
  56.   "LD (FF*h),A","POP HL","LD (FF00h+C),A","EX HL,(SP)","DB E4h","PUSH HL","AND *h","RST 20h",
  57.   "ADD SP,@h","LD PC,HL","LD (#h),A","DB EBh","DB ECh","PREFIX EDh","XOR *h","RST 28h",
  58.   "LD A,(FF*h)","POP AF","LD A,(FF00h+C)","DI","DB F4h","PUSH AF","OR *h","RST 30h",
  59.   "LDHL SP,@h","LD SP,HL","LD A,(#h)","EI","DB FCh","DB FDh","CP *h","RST 38h"
  60. };
  61.  
  62. char *MnemonicsCB[256] =
  63. {
  64.   "RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (HL)","RLC A",
  65.   "RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (HL)","RRC A",
  66.   "RL B","RL C","RL D","RL E","RL H","RL L","RL (HL)","RL A",
  67.   "RR B","RR C","RR D","RR E","RR H","RR L","RR (HL)","RR A",
  68.   "SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (HL)","SLA A",
  69.   "SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (HL)","SRA A",
  70.   "SWAP B","SWAP C","SWAP D","SWAP E","SWAP H","SWAP L","SWAP (HL)","SWAP A",
  71.   "SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (HL)","SRL A",
  72.   "BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(HL)","BIT 0,A",
  73.   "BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(HL)","BIT 1,A",
  74.   "BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(HL)","BIT 2,A",
  75.   "BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(HL)","BIT 3,A",
  76.   "BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(HL)","BIT 4,A",
  77.   "BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(HL)","BIT 5,A",
  78.   "BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(HL)","BIT 6,A",
  79.   "BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(HL)","BIT 7,A",
  80.   "RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(HL)","RES 0,A",
  81.   "RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(HL)","RES 1,A",
  82.   "RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(HL)","RES 2,A",
  83.   "RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(HL)","RES 3,A",
  84.   "RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(HL)","RES 4,A",
  85.   "RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(HL)","RES 5,A",
  86.   "RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(HL)","RES 6,A",
  87.   "RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(HL)","RES 7,A",
  88.   "SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(HL)","SET 0,A",
  89.   "SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(HL)","SET 1,A",
  90.   "SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(HL)","SET 2,A",
  91.   "SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(HL)","SET 3,A",
  92.   "SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(HL)","SET 4,A",
  93.   "SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(HL)","SET 5,A",
  94.   "SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(HL)","SET 6,A",
  95.   "SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(HL)","SET 7,A"
  96. };
  97.  
  98. char *MnemonicsED[256] =
  99. {
  100.   "FUCK00","FUCK01","FUCK02","FUCK03","FUCK04","FUCK05","FUCK06","FUCK07",
  101.   "FUCK08","FUCK09","FUCK0A","FUCK0B","FUCK0C","FUCK0D","FUCK0E","FUCK0F",
  102.   "FUCK10","FUCK11","FUCK12","FUCK13","FUCK14","FUCK15","FUCK16","FUCK17",
  103.   "FUCK18","FUCK19","FUCK1A","FUCK1B","FUCK1C","FUCK1D","FUCK1E","FUCK1F",
  104.   "FUCK20","FUCK21","FUCK22","FUCK23","FUCK24","FUCK25","FUCK26","FUCK27",
  105.   "FUCK28","FUCK29","FUCK2A","FUCK2B","FUCK2C","FUCK2D","FUCK2E","FUCK2F",
  106.   "FUCK30","FUCK31","FUCK32","FUCK33","FUCK34","FUCK35","FUCK36","FUCK37",
  107.   "FUCK38","FUCK39","FUCK3A","FUCK3B","FUCK3C","FUCK3D","FUCK3E","FUCK3F",
  108.   "FUCK40","FUCK41","SBC HL,BC","LD (#h),BC","FUCK44","RETN","IM 0","LD I,A",
  109.   "FUCK48","FUCK49","ADC HL,BC","LD BC,(#h)","FUCK4C","RETI","FUCK4E","LD R,A",
  110.   "FUCK50","FUCK51","SBC HL,DE","LD (#h),DE","FUCK54","FUCK55","IM 1","LD A,I",
  111.   "FUCK58","FUCK59","ADC HL,DE","LD DE,(#h)","FUCK5C","FUCK5D","IM 2","LD A,R",
  112.   "FUCK60","FUCK61","SBC HL,HL","LD (#h),HL","FUCK64","FUCK65","FUCK66","RRD",
  113.   "FUCK68","FUCK69","ADC HL,HL","LD HL,(#h)","FUCK6C","FUCK6D","FUCK6E","RLD",
  114.   "FUCK70","FUCK71","SBC HL,SP","LD (#h),SP","FUCK74","FUCK75","FUCK76","FUCK77",
  115.   "FUCK78","FUCK79","ADC HL,SP","LD SP,(#h)","FUCK7C","FUCK7D","FUCK7E","FUCK7F",
  116.   "FUCK80","FUCK81","FUCK82","FUCK83","FUCK84","FUCK85","FUCK86","FUCK87",
  117.   "FUCK88","FUCK89","FUCK8A","FUCK8B","FUCK8C","FUCK8D","FUCK8E","FUCK8F",
  118.   "FUCK90","FUCK91","FUCK92","FUCK93","FUCK94","FUCK95","FUCK96","FUCK97",
  119.   "FUCK98","FUCK99","FUCK9A","FUCK9B","FUCK9C","FUCK9D","FUCK9E","FUCK9F",
  120.   "LDI","CPI","FUCKA2","FUCKA3","FUCKA4","FUCKA5","FUCKA6","FUCKA7",
  121.   "LDD","CPD","FUCKAA","FUCKAB","FUCKAC","FUCKAD","FUCKAE","FUCKAF",
  122.   "LDIR","CPIR","FUCKB2","FUCKB3","FUCKB4","FUCKB5","FUCKB6","FUCKB7",
  123.   "LDDR","CPDR","FUCKBA","FUCKBB","FUCKBC","FUCKBD","FUCKBE","FUCKBF",
  124.   "FUCKC0","FUCKC1","FUCKC2","FUCKC3","FUCKC4","FUCKC5","FUCKC6","FUCKC7",
  125.   "FUCKC8","FUCKC9","FUCKCA","FUCKCB","FUCKCC","FUCKCD","FUCKCE","FUCKCF",
  126.   "FUCKD0","FUCKD1","FUCKD2","FUCKD3","FUCKD4","FUCKD5","FUCKD6","FUCKD7",
  127.   "FUCKD8","FUCKD9","FUCKDA","FUCKDB","FUCKDC","FUCKDD","FUCKDE","FUCKDF",
  128.   "FUCKE0","FUCKE1","FUCKE2","FUCKE3","FUCKE4","FUCKE5","FUCKE6","FUCKE7",
  129.   "FUCKE8","FUCKE9","FUCKEA","FUCKEB","FUCKEC","FUCKED","FUCKEE","FUCKEF",
  130.   "FUCKF0","FUCKF1","FUCKF2","FUCKF3","FUCKF4","FUCKF5","FUCKF6","FUCKF7",
  131.   "FUCKF8","FUCKF9","FUCKFA","FUCKFB","FUCKFC","FUCKFD","FUCKFE","FUCKFF"
  132. };
  133.  
  134. void HexByte(char *S,byte V)
  135. {
  136.   static char Digits[]="0123456789ABCDEF";
  137.   *S++=Digits[V>>4];*S++=Digits[V&0x0F];*S='\0';
  138. }
  139.  
  140. void HexWord(char *S,word V)
  141. { HexByte(S,V>>8);HexByte(S+2,V&0xFF); }
  142.  
  143. int DAsm(char *S,byte *A)
  144. {
  145.   char H[3],*T,*P;
  146.   byte *B,J;
  147.  
  148.   B=A;
  149.  
  150.   switch(*B)
  151.   {
  152.     case 0xCB: B++;T=MnemonicsCB[*B++];break;
  153.     case 0xED: B++;T=MnemonicsED[*B++];break;
  154.     default:   T=Mnemonics[*B++];
  155.   }
  156.  
  157.   if(P=strchr(T,'*'))
  158.   {
  159.     strncpy(S,T,P-T);S[P-T]='\0';
  160.     HexByte(H,*B++);strcat(S,H);
  161.     strcat(S,P+1);
  162.   }
  163.   else
  164.     if(P=strchr(T,'@'))
  165.     {
  166.       strncpy(S,T,P-T);S[P-T]='\0';
  167.       strcat(S,*B&0x80? "-":"+");
  168.       J=*B&0x80? 256-*B:*B;B++;
  169.       HexByte(H,J);strcat(S,H);
  170.       strcat(S,P+1);
  171.     }
  172.     else
  173.       if(P=strchr(T,'#'))
  174.       {
  175.         strncpy(S,T,P-T);S[P-T]='\0';
  176.         HexByte(H,*(++B));strcat(S,H);
  177.         HexByte(H,*(B-1));strcat(S,H);
  178.         B++;strcat(S,P+1);
  179.       }
  180.       else strcpy(S,T);
  181.  
  182.   return(B-A);
  183. }
  184.  
  185. int main(int argc,char *argv[])
  186. {
  187.   FILE *F;
  188.   long Counter;  
  189.   int N,I;
  190.   byte Buf[16];
  191.   char S[128],H[5];
  192.  
  193.   if(argc!=2)
  194.   {
  195.     puts("GameBoy Disassembler 1.2 by Marat Fayzullin  (C)FMS 1995");
  196.     puts("Usage: dasm <input file>");
  197.     return(0);
  198.   }
  199.     
  200.   if(!(F=fopen(argv[1],"rb")))
  201.   { printf("\n%s: Can't open file %s\n",argv[0],argv[1]);return(1); }
  202.   
  203.   Counter=0L;N=0;
  204.   while(N+=fread(Buf+N,1,16-N,F))
  205.   {
  206.     N+=fread(Buf+N,1,16-N,F);
  207.     if(N<16) memset(Buf+N,0,16-N);
  208.     I=DAsm(S,Buf);
  209.     HexWord(H,(Counter>>16)&0xFFFF);printf(H);
  210.     HexWord(H,Counter&0xFFFF);printf(H);
  211.     printf(":\t%s\n",S);
  212.     Counter+=I;N-=I;
  213.     if(N) memcpy(Buf,Buf+16-N,N);
  214.   }
  215.  
  216.   fclose(F);return(0);
  217. }
  218.